package ru.hh.team02.chat.utils;

import java.util.List;

/**
 * A BlockingQueue interface requiring for a thread to be blocked
 * inside get method if the queue is empty.
 * Also it requires notifying a thread on message add.
 * Also this queue should provide addAll method
 * with only one acquisition of monitor per adding
 * all the elements, which should notify all waiting threads
 * in the get method.
 *
 * @param <T>
 */
public interface BatchBlockingQueue<T> {

    /**
     * Get a message from the queue.
     * If the queue is empty, block the thread until a new message is added to the queue.
     *
     * @return T
     * @throws InterruptedException When trying to get from the queue being empty and in terminating mode.
     */
    T get() throws InterruptedException;

    /**
     * Add T object to the queue
     *
     * @param obj object to add to the queue
     * @return false if the queue in terminating mode
     */
    boolean add(T obj);

    /**
     * Add T object to the beginning of the queue
     *
     * @param obj object to add to the queue
     * @return false if the queue in terminating mode
     */
    boolean addFront(T obj);

    /**
     * Add a set of objects to the queue.
     *
     * @param objects Set of objects to add to the queue
     * @return false if the queue in terminating mode
     */
    boolean addAll(List<T> objects);

    /**
     * Add a set of objects to the front of the queue.
     *
     * @param objects Set of objects to add to the queue
     * @return false if the queue in terminating mode
     */
    boolean addAllFront(List<T> objects);

    /**
     * Set queue to terminating mode.
     * This method will not stop threads unitl all the messages are sent
     * from the queue.
     */
    void terminate();

}
